範圍鍊在 JavaScript 一堆奇奇怪怪的觀念中算是簡單好懂的,簡單來說就是:
『函示內沒有對應的變數、常數或是函示時,他會往外層尋找』
這邊一樣用程式碼來說明。
  function playGame(){
		const gaming = 'PS5'
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 PS5 玩遊戲
上面這段 gaming 在函示內,因此能正確顯示,這段好像廢話,不過接下來我們試者把 gaming 移到外層全域看看結果如何:
const gaming = 'PS5'
  function playGame(){
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 PS5 玩遊戲
結果是一樣的,上面 playGame() 函式中因為本身沒有 gaming  常數,因此他會到外層也是全域 (window) ,來獲得 gaming  常數的資料。
接下來便是在函示內外都新增兩個 gaming  來看看結果如何
const gaming = 'PS5'
  function playGame(){
	const gaming = 'Switch'
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 Switch 玩遊戲
所以結果就是當函示內有相關資料時,變不會往外層尋找,而是直接使用函示內資料。
(因為 const、 let  提升的狀況不一樣,這邊範例先改為使用 var , const、 let  會到介紹他們的章節再來提及)
JavaScript 實際編譯並執行程式碼時,會分為兩種階段:
等創造階段執行完畢,才會進入執行階段,創造階段有幾個重點:
而執行階段的重點則是:
XX() 。這邊使用上面程式碼,並稍微調一下順序就可驗證上面提到的創造階段。
console.log(gaming) // undefined
var gaming = 'PS5'
playGame() //我要用 PS5 玩遊戲
  function playGame(){
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
console.log(gaming)  這段會因為變數被提升,但尚未賦值因此是 cosnole 會回傳 undefined
playGame()  則是 function playGame() 函示會因為提升效果,而先比被呼叫函示的 playGame()  建立,因此 console 可以正確顯示。
因為提升這個 特性 會讓上面的程式碼,在編譯順序變為:
// 創造階段
//函示優先提升
function playGame(){
  console.log(`我要用 ${gaming} 玩遊戲`)
}
var gaming 
// 執行階段
console.log(gaming) // undefined
gaming = 'PS5'
playGame() //我要用 PS5 玩遊戲
最後要說的是,Hoisting 只是概念,只是幫助我們理解,程式碼在編譯時會這麼做,但他仍只是一種概念, 這點 MDN 文件也有說明到:
提升(Hoisting)是在 ECMAScript® 2015 Language Specification 裡面找不到的專有名詞。它是一種釐清 JaveScript 在執行階段內文如何運行的思路(尤其是在創建和執行階段)。